package org.arquillian.cube.docker.impl.await;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.arquillian.cube.docker.impl.client.config.Await;
import org.arquillian.cube.docker.impl.docker.DockerClientExecutor;
import org.arquillian.cube.spi.Cube;
import org.arquillian.cube.spi.await.AwaitStrategy;
public class CustomAwaitStrategyInstantiator implements AwaitStrategy {
private Cube<?> cube;
private DockerClientExecutor dockerClientExecutor;
private Await params;
public CustomAwaitStrategyInstantiator(Cube<?> cube, DockerClientExecutor dockerClientExecutor, Await params) {
this.cube = cube;
this.dockerClientExecutor = dockerClientExecutor;
this.params = params;
}
@Override
public boolean await() {
String className = this.params.getStrategy();
try {
Class<? extends AwaitStrategy> customStrategy = (Class<? extends AwaitStrategy>) Class.forName(className);
AwaitStrategy customStrategyInstance = customStrategy.newInstance();
// Inject if there is a field of type Cuube, DockerClientExecutor or Await.
final Field[] fields = customStrategyInstance.getClass().getDeclaredFields();
for (Field field : fields) {
if (field.getType().isAssignableFrom(Cube.class)) {
field.setAccessible(true);
field.set(customStrategyInstance, this.cube);
} else {
if (field.getType().isAssignableFrom(DockerClientExecutor.class)) {
field.setAccessible(true);
field.set(customStrategyInstance, this.dockerClientExecutor);
} else {
if (field.getType().isAssignableFrom(Await.class)) {
field.setAccessible(true);
field.set(customStrategyInstance, this.params);
}
}
}
}
// Inject if there is a setter for Cube, DockerClientExecutor or Await
for (PropertyDescriptor propertyDescriptor :
Introspector.getBeanInfo(customStrategyInstance.getClass()).getPropertyDescriptors()) {
final Method writeMethod = propertyDescriptor.getWriteMethod();
if (writeMethod != null) {
if (writeMethod.getParameterTypes()[0].isAssignableFrom(Cube.class)) {
writeMethod.invoke(customStrategyInstance, this.cube);
} else {
if (writeMethod.getParameterTypes()[0].isAssignableFrom(DockerClientExecutor.class)) {
writeMethod.invoke(customStrategyInstance, this.dockerClientExecutor);
} else {
if (writeMethod.getParameterTypes()[0].isAssignableFrom(Await.class)) {
writeMethod.invoke(customStrategyInstance, this.params);
}
}
}
}
}
// Finally we call the await method
return customStrategyInstance.await();
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | IntrospectionException | InvocationTargetException e) {
throw new IllegalArgumentException(e);
}
}
}